package cart

import (
	// "fmt"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/utils/pointy"
	"mall/service/product/rpc/productclient"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

// StockCheckHandler 商品库存操作handler
type StockCheckHandler struct {
	// 合成复用Next
	Next
}

// Do 检查库存
func (h *StockCheckHandler) Do(c *Context) (err error) {
	if !c.Resp.StockValid {
		return
	}

	// logx.Infow("检查库存...")

	var stocks []*productclient.ProductVariationStock
	skuIdQtyMap := make(map[uint64]uint32)
	for _, v := range c.Resp.List {
		if v.Status != nil && v.SkuId != nil && v.Quantity != nil && *v.Status > 0 && *v.SkuId > 0 && *v.Quantity > 0 {
			if num, ok := skuIdQtyMap[*v.SkuId]; !ok {
				skuIdQtyMap[*v.SkuId] = *v.Quantity
			} else {
				skuIdQtyMap[*v.SkuId] = num + *v.Quantity
			}
		}
	}
	for skuId, qty := range skuIdQtyMap {
		stocks = append(stocks, &productclient.ProductVariationStock{
			Id:    skuId,
			Stock: qty,
		})
	}
	if len(stocks) == 0 {
		return
	}

	res, err := c.SvcCtx.ProductRpc.CheckAndSubtractStock(c.Ctx, &productclient.CheckAndSubtractStockReq{
		Data:      stocks,
		CheckOnly: pointy.GetPointer(uint32(1)),
	})
	if err != nil {
		logx.Errorw("StockCheckHandler CheckAndSubtractStock err", logx.Field("detail", err.Error()))
		// logrus.Info(fmt.Sprintf("StockCheckHandler CheckAndSubtractStock err: %+v", err))
	}

	if res != nil && len(res.Msg) > 0 {
		// logrus.Info(fmt.Sprintf("StockCheckHandler CheckAndSubtractStock res: %+v", res))
		if skuIds := strings.Split(res.Msg, ","); len(skuIds) > 0 { // 返回库存无效的SKU ID
			skuIdMap := make(map[uint64]struct{})
			for _, skuId := range skuIds {
				if i, err := strconv.ParseInt(skuId, 10, 64); err == nil {
					skuIdMap[uint64(i)] = struct{}{}
				}
			}

			isValid := true // 库存有效
			for idx, v := range c.Resp.List {
				if v.SkuId != nil {
					if _, ok := skuIdMap[*v.SkuId]; ok {
						isValid = false
						c.Resp.List[idx].Status = pointy.GetPointer(globalkey.StatusOverSize)
					}
				}
			}
			if !isValid {
				c.Resp.StockValid = false
			}
		}
	}

	return
}
